/**
 * 
 */
package com.ginger.zookeeper;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooDefs.Perms;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ginger.zookeeper.utils.AclUtils;

/**
 * @Description: ZooKeeper节点操作类
 * @author 姜锋
 * @date 2018年8月20日 上午10:58:50
 * @version V1.0
 */
public class ZKNodeOpteator implements Watcher {
	//开启日志
	final static Logger log = LoggerFactory.getLogger(ZKNodeOpteator.class);
	// 服务端地址
	public static final String connectionString = "www.justginger.top:2181,www.justginger.top:2182,www.justginger.top:2183";
	// session过期时间
	public static final Integer sessionTimeout = 5000;
	private ZooKeeper zooKeeper = null;
	private static Stat stat = new Stat();
	private static CountDownLatch countDown = new CountDownLatch(1);

	public ZKNodeOpteator() {
	}
	public ZKNodeOpteator(String connectionString) {
		try {
			zooKeeper = new ZooKeeper(connectionString, sessionTimeout, new ZKNodeOpteator());
		} catch (Exception e) {
			e.printStackTrace();
			if (zooKeeper != null) {
				try {
					zooKeeper.close();
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}
		}
	}
	/**
	 * @Description: 创建ZooKeeper节点 @author 姜锋 @date 2018年8月20日 上午11:17:11 @param @param
	 *               path @param @param data @param @param acls @return void @throws
	 */
	public boolean createZKNode(String path, byte[] data, List<ACL> acls) {
		try {
			/**
			 * 同步或者异步创建节点,都不支持子节点的递归创建,异步有一个callback函数 参数: path: 存储的路径 data: 存储的数据的byte[] acl:
			 * 控制权限的策略 Ids.OPEN_ACL_UNSAFE --> world:anyone:cdrwa Ids.CREATOR_ALL_ACL -->
			 * auth:user:password:cdrwa createMode : 节点类型,是一个枚举 PERSISTENT 持久节点
			 * PERSISTENT_SEQUENTIAL 持久顺序节点 EPHEMERAL 临时节点 EPHEMERAL_SEQUENTIAL 临时顺序节点
			 */
			// result = zooKeeper.create(path, data, acls, CreateMode.PERSISTENT_SEQUENTIAL);
			String ctx = "{'create':'sucess'}";
			zooKeeper.create(path, data, acls, CreateMode.PERSISTENT, new CreateCallback(), ctx);
			Thread.sleep(2000);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	public void getChildrenList(String path) {
		// List<String> strChidList = zkServer.getZooKeeper().getChildren("/ginger", true);
		/*
		 * for (String str : strChidList) { System.out.println(str); }
		 */
		// 异步调用
		String ctx = "{'callback':'ChildreanCallback'}";
		getZooKeeper().getChildren(path, true, new ChildreanCallback(), ctx);
		getZooKeeper().getChildren(path, true, new Childrean2Callback(), ctx);
	}
	
	public boolean nodeExist(String path) throws KeeperException, InterruptedException {
		
		Stat stat = getZooKeeper().exists(path, true);
		if(null !=stat) {
			
			return true;
		}else {
			
			return false;
		}
	}
	
	public byte[] getNodeData(String path) throws KeeperException, InterruptedException {
		return  getZooKeeper().getData(path, true, stat);
	}
	
	public static void main(String[] args) throws Exception {
		ZKNodeOpteator zkServer = new ZKNodeOpteator(connectionString);
		// 创建zk节点 -- 任何人都可以访问
		//zkServer.createZKNode("/testNode", "这是Java写的".getBytes(), Ids.OPEN_ACL_UNSAFE);
		// 创建zk节点 -- 自定义用户认证访问
		List<ACL> acls = new ArrayList<>();
		Id ginger1 = new Id("digest", AclUtils.getDigestUserPwd("ginger1:ginger1"));
		Id ginger2 = new Id("digest", AclUtils.getDigestUserPwd("ginger2:ginger2"));
		//赋予ginger1 所有权限
		acls.add(new ACL(Perms.ALL, ginger1));
		//赋予ginger2 删除权限
		acls.add(new ACL(Perms.DELETE, ginger2));
		//赋予ginger2 读取和写入前线
		acls.add(new ACL(Perms.READ | Perms.WRITE, ginger2));
		zkServer.createZKNode("/ginger/java0902","大休息天闲的搞Java".getBytes() , acls);
		
		// 修改节点
		// Stat status = zkServer.getZooKeeper().setData("/testNode", "666
		// 这个真的是java写的".getBytes(), 0);
		// log.debug("新的版本"+status.getVersion());
		// 删除节点
		// zkServer.getZooKeeper().delete("/testNode", 1);
		// 查询子节点
		// zkServer.getChildrenList();
		//查询节点是否存在
		//zkServer.nodeExist(path);
	}
	/**
	 * @return zooKeeper
	 */
	public ZooKeeper getZooKeeper() {
		return zooKeeper;
	}
	/**
	 * @param zooKeeper 要设置的 zooKeeper
	 */
	public void setZooKeeper(ZooKeeper zooKeeper) {
		this.zooKeeper = zooKeeper;
	}
	@Override
	public void process(WatchedEvent event) {
		try {
			if (event.getType() == EventType.NodeChildrenChanged) {
				System.out.println("触发 NodeChildrenChanged");
				List<String> strChidList = new ZKNodeOpteator(connectionString).getZooKeeper()
						.getChildren(event.getPath(), true);
				for (String str : strChidList) {
					System.out.println(str);
				}
				countDown.countDown();
			} else if (event.getType() == EventType.NodeCreated) {
				System.out.println("触发 NodeCreated");
			} else if (event.getType() == EventType.NodeDataChanged) {
				System.out.println("触发 NodeDataChanged");
			} else if (event.getType() == EventType.NodeDeleted) {
				System.out.println("触发 NodeDeleted");
			}
		} catch (KeeperException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
